package com.DT.netTool;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;


import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


import static com.DT.netTool.PingNetUtil.debugLog;
import static com.DT.netTool.PingNetUtil.getTime;


/**
 * 调用系统命令,暂无调用,留作参考用途
 * */
public class ScriptUtil {
    private static final String TAG = ScriptUtil.class.getSimpleName();
    // 固定
    public static final String SCRIPT_FILE_NAME = "script";

    private static boolean mHaveRoot = false;

    /**
     *   判断机器Android是否已经root，即是否获取root权限
     */
    public static boolean haveRoot() {
        if (!mHaveRoot) {
            int ret = execRootCmdSilent("echo test"); // 通过执行测试命令来检测
            if (ret != -1) {
                Log.i(TAG, "have root!");
                mHaveRoot = true;
            } else {
                Log.i(TAG, "not root!");
            }
        } else {
            Log.i(TAG, "mHaveRoot = true, have root!");
        }
        return mHaveRoot;
    }

    /**
     * 定义一个方法用于执行cmd命令并且输出结果,非root命令
     * @return
     */
    public static String execUserCmd(String cmd, Handler pingHandler) {
        PingNetEntity pingNetEntity=new PingNetEntity("10.1.1.2",4,4);
        String line = null;
        Process process = null;


        BufferedReader successReader = null;
        String command = "ping -c " + pingNetEntity.getPingCount() + " -w " + pingNetEntity.getPingWtime() + " " + pingNetEntity.getIp();
//        String command = "ping -c " + pingCount + " " + host;
        try {
            process = Runtime.getRuntime().exec(cmd);
            if (process == null) {
                debugLog( "ping fail:process is null.");
                pingNetEntity.getResultBuffer().append( "ping fail:process is null.");
                pingNetEntity.setPingTime(null);
                pingNetEntity.setResult(false);
                return pingNetEntity.getResultBuffer().toString();
            }
            successReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while ((line = successReader.readLine()) != null) {
                debugLog( line);
                pingNetEntity.getResultBuffer().append( line);
                /*发送到UI*/
                Message sendMsg=new Message();
                sendMsg.what=9999;
                sendMsg.obj=line+'\n';
                pingHandler.sendMessage(sendMsg);
                /*发送到UI*/
                String time;
                if ((time = getTime(line)) != null) {
                    pingNetEntity.setPingTime(time);
                }
            }
            int status = process.waitFor();
            if (status == 0) {
                debugLog( "exec cmd success:" + command);
//                append(pingNetEntity.getResultBuffer(), "exec cmd success:" + command);
                pingNetEntity.setResult(true);
            } else {
                debugLog( "exec cmd fail.");
//                append(pingNetEntity.getResultBuffer(), "exec cmd fail.");
                pingNetEntity.setPingTime(null);
                pingNetEntity.setResult(false);
            }
            debugLog( "exec finished.");
//            append(pingNetEntity.getResultBuffer(), "exec finished.");
        } catch (IOException e) {
            debugLog( String.valueOf(e));
            pingNetEntity.getResultBuffer().append(String.valueOf(e));
        } catch (InterruptedException e) {
            debugLog( String.valueOf(e));
        } finally {
            debugLog( "ping exit.");
            if (process != null) {
                process.destroy();
            }
            if (successReader != null) {
                try {
                    successReader.close();
                } catch (IOException e) {
                    debugLog( String.valueOf(e));
                }
            }
        }
        debugLog( pingNetEntity.getResultBuffer().toString());
        return pingNetEntity.getResultBuffer().toString();
    }

    /**
     * 定义一个方法用于执行cmd命令并且输出结果
     */
    public static String execRootCmd(String cmd) {
        String result = "";
        DataOutputStream dos = null;
        DataInputStream dis = null;

        try {
            Process p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令
            dos = new DataOutputStream(p.getOutputStream());
            dis = new DataInputStream(p.getInputStream());

            Log.i(TAG, cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            String line = null;
            while ((line = dis.readLine()) != null) {
                Log.d("result", line);
                result += line;
            }
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG,"execRootCmd： 执行cmd指令: " + cmd + "  | 异常：  " + e.getMessage());
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG,"execRootCmd： 关闭dos异常 : " + cmd + "  | 异常：  " + e.getMessage());
                }
            }
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG,"execRootCmd： 关闭dis异常: " + cmd + "  | 异常：  " + e.getMessage());
                }
            }
        }
        return result;
    }

    /**
     * 定义一个方法用于执行命令但不关注结果输出
     */
    public static int execRootCmdSilent(String cmd) {
        int result = -1;
        DataOutputStream dos = null;

        try {
            Process p = Runtime.getRuntime().exec("su");
            dos = new DataOutputStream(p.getOutputStream());

            Log.i(TAG, cmd);
            dos.writeBytes(cmd + "\n");
            dos.flush();
            dos.writeBytes("exit\n");
            dos.flush();
            p.waitFor();
            result = p.exitValue();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "execRootCmdSilent: adb指令: " + cmd + " | 执行异常：  " + e.getMessage());
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * 定义一个方法用于执行静默安装 (调用adb指令 pm install )
     * @param packageName　 　调用installSilent函数的应用包名
     * @param filePath 　　　　静默安装应用的apk路径
     * @return 0 安装成功
     * 　　　　　　　 1 文件不存在
     * 　　　　　　　 2 安装失败
     */
    public static int installSilent(String packageName,String filePath) {
        File file = new File(filePath);
        if (filePath == null || filePath.length() == 0 || file == null || file.length() <= 0 || !file.exists() || !file.isFile()) {
            return 1;
        }
        //pm install -i 包名 --user 0 -r apkpath
        String[] args = { "pm", "install","-i",packageName,"--user","0", "-r", filePath };
        ProcessBuilder processBuilder = new ProcessBuilder(args);
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder errorMsg = new StringBuilder();
        int result;
        try {
            process = processBuilder.start();
            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String s;
            while ((s = successResult.readLine()) != null) {
                successMsg.append(s);
                Log.d(TAG, "while successMsg s:" + s);
            }
            while ((s = errorResult.readLine()) != null) {
                errorMsg.append(s);
                Log.d(TAG, "while errorMsg s:" + s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }

        if (successMsg.toString().contains("Success") || successMsg.toString().contains("success")) {
            result = 0;
        } else {
            result = 2;
        }
        Log.d("installSilent", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg);
        return result;
    }

    /**
     * 定义一个方法用于执行静默卸载 (调用adb shell指令 pm uninstall )
     * @param packageName　 　调用installSilent函数的应用包名
     */
    public static String uninstallSilent(String packageName) {
        //pm uninstall 包名
        String result = ScriptUtil.execRootCmd("pm uninstall " + packageName);
        return result;
    }

    /**
     * 定义一个方法用于通过adb指令执行 以太网Mac地址设置
     * @param macAddress
     */
    public static void setEthernetMacAddress(String macAddress){
        if (TextUtils.isEmpty(macAddress)) {
            Log.e(TAG, "setEthernetMacAddress: 输入的mac地址为null，无法执行");
            return;
        }
        String[] commands = new String[3];
        commands[0] = "ifconfig eth0 down";
        commands[1] = "busybox ip link set eth0 address " + macAddress;
        commands[2] = "ifconfig eth0 up";

        for (String command : commands) {
            String result = execRootCmd(command);
//            Log.i(TAG, "发送adb指令执行 Mac地址修改,当前执行的指令为： " + command + "  执行结果为：  " + result);
        }
    }

    /**
     * 定义一个方法用于通过adb指令进行重启操作
     */
    public static void reboot(){
        execRootCmdSilent("reboot");
    }

    /**
     * 定义一个方法用于开启ADB网络调试
     */
    public static void openNetWorkAdb() {
        String commands[] = new String[4];
        commands[0] = "setprop service.adb.tcp.port 5555";
        commands[1] = "stop adbd";
        commands[2] = "start adbd";
        commands[3] = "exit";

        for (String command : commands) {
            String result = execRootCmd(command);
            Log.i(TAG, "发送adb指令执行 Adb网络调试,当前执行的指令为： " + command + "  执行结果为：  " + result);
        }
    }


    /**
     *
     * 【重要提示】 2019.8.2 该方法只适用于A33和A64设备，在 rk3399 Android 7.1.2 上已失效，请勿调用
     *
     * 示例代码
     * String[] commands = new String[4];
     * commands[0] = "su";
     * commands[1] = "mount -o remount,rw /system";
     * commands[2] = "cp /data/user/0/com.taichuan.sp/databases/bugly_db_ /system/xbin/bugly_db_";
     * commands[3] = "chmod 755 /system/xbin/bugly_db_";
     * ScriptUtil.execute(commands);
     */
    public static void execute(String[] commands) {
        // 固定
        File file = new File("/data/app/script/" + SCRIPT_FILE_NAME + ".sh");
        File dir = file.getParentFile();
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (file.exists()) {
            file.delete();
        }
        FileWriter fileWriter = null;
        try {
            file.createNewFile();
            fileWriter = new FileWriter(file);
            String fileContext = "#! /system/bin/sh \n";
            fileWriter.write(fileContext);
            for (int i = 0, count = commands.length; i < count; i++) {
                fileWriter.write(commands[i]);
                fileWriter.write("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"指令执行异常：  " + e.getMessage());
        } finally {
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            Log.e(TAG,"即将执行的adb指令内容为：  " + file.getAbsolutePath());
            Runtime.getRuntime().exec(file.getAbsolutePath());
            Log.e(TAG,"即将执行的adb指令内容执行完毕----");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"IOException 指令执行异常：  " + e.getMessage());
        }
        set("ctl.stop", SCRIPT_FILE_NAME);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Log.e(TAG,"InterruptedException  指令执行异常：  " + e.getMessage());
        }
        set("ctl.start", SCRIPT_FILE_NAME);
        Log.v(TAG, "script:" + get("init.svc." + SCRIPT_FILE_NAME));
    }

    /**
     *
     * TODO App需要在manifest添加android:sharedUserId="android.uid.system"
     *
     * @param key
     * @return
     */
    public static String get(String key) {
        String result = "";
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");

            Method get = c.getMethod("get", String.class);
            result = (String) get.invoke(c, key);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Log.e(TAG,"get()  " + key + "  ClassNotFoundException 指令执行异常：  " + e.getMessage());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            Log.e(TAG,"get()  " + key + "  NoSuchMethodException 指令执行异常：  " + e.getMessage());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            Log.e(TAG,"get()  " + key + "  IllegalAccessException 指令执行异常：  " + e.getMessage());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            Log.e(TAG,"get()  " + key + "  IllegalArgumentException 指令执行异常：  " + e.getMessage());
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            Log.e(TAG,"get()  " + key + "  InvocationTargetException 指令执行异常：  " + e.getMessage());
        }
        return result;
    }

    /**
     * TODO App需要在manifest添加android:sharedUserId="android.uid.system"
     *
     * @param key
     * @param val
     */
    public static void set(String key, String val) {
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method set = c.getMethod("set", String.class, String.class);
            set.invoke(c, key, val);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Log.e(TAG,"set() key: " + key + " value: " + val + "  ClassNotFoundException 指令执行异常：  " + e.getMessage());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            Log.e(TAG,"set() key: " + key + " value: " + val + "  NoSuchMethodException 指令执行异常：  " + e.getMessage());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            Log.e(TAG,"set() key: " + key + " value: " + val + "  IllegalAccessException 指令执行异常：  " + e.getMessage());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            Log.e(TAG,"set() key: " + key + " value: " + val + "  IllegalArgumentException 指令执行异常：  " + e.getMessage());
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            Log.e(TAG,"set() key: " + key + " value: " + val + "  InvocationTargetException 指令执行异常：  " + e.getMessage());
        }
    }
}
